package com.example.apidocserver.domain.space.event.impl;

import com.example.apidocserver.domain.system.entity.AllEnum;
import com.example.apidocserver.domain.space.event.AllEnumDomainEvent;
import com.example.apidocserver.domain.system.service.AllEnumService;
import com.example.apidocserver.infrastructure.util.result.ParamException;
import com.example.apidocserver.interfaces.dto.IdsDto;
import com.example.apidocserver.interfaces.vo.AllEnumVo;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 系统枚举域事件
 *
 * @author xyqlg
 */
@Service
public class AllEnumDomainEventImpl implements AllEnumDomainEvent {
    @Resource
    private AllEnumService allEnumService;

    @Override
    public AllEnumVo findAllEnum() {
        int classType = -999;
        List<AllEnum> allEnums = allEnumService.queryAll();
        Map<Integer, List<AllEnum>> parentIdAndChildrenMap = allEnums.stream()
                .collect(Collectors.groupingBy(allEnum -> Optional.ofNullable(allEnum.getEnumType()).orElse(classType)));
        List<AllEnum> enumClassList = parentIdAndChildrenMap.get(classType);
        if (CollectionUtils.isEmpty(enumClassList)) {
            throw new ParamException("没有初始数据。");
        }
        AllEnum enumClass = enumClassList.get(0);
        List<AllEnum> topEnumList = parentIdAndChildrenMap.get(enumClass.getId());
        if (CollectionUtils.isEmpty(topEnumList)) {
            return new AllEnumVo(Collections.emptyList(), new AllEnum(null, enumClass.getId()));
        }

        for (AllEnum allEnum : topEnumList) {
            allEnum.setChildren(parentIdAndChildrenMap.get(allEnum.getId()));
        }
        return new AllEnumVo(topEnumList, new AllEnum(null, enumClass.getId()));
    }

    @Override
    @Transactional
    public AllEnum upsertAllEnum(AllEnum allEnum) {
        if (Objects.isNull(allEnum.getEnumType())) {
            throw new ParamException("枚举类型不能为空");
        }
        Date now = new Date();
        if (Objects.isNull(allEnum.getId())) {
            int maxOrder = allEnumService.queryMaxOrder(allEnum.getEnumType());
            // 枚举分类
            allEnum.setOrderNo(maxOrder + 1).setCreateTime(now).setUpdateTime(now);
            AllEnum insert = allEnumService.insert(allEnum);
            if (!CollectionUtils.isEmpty(allEnum.getChildren())) {
                int order = 1;
                for (AllEnum child : allEnum.getChildren()) {
                    child.setEnumType(insert.getId()).setCreateTime(now).setUpdateTime(now);
                    if (Objects.isNull(child.getOrderNo())) {
                        child.setOrderNo(order++);
                    }
                }
                allEnumService.upsert(allEnum.getChildren());
            }
        } else {
            allEnum.setUpdateTime(now);
            if (CollectionUtils.isEmpty(allEnum.getChildren())) {
                allEnumService.update(allEnum);
                return allEnum;
            }
            List<AllEnum> allEnums = new ArrayList<>(allEnum.getChildren().size() + 1);
            for (AllEnum child : allEnum.getChildren()) {
                child.setEnumType(allEnum.getEnumType()).setUpdateTime(now);
                if (Objects.isNull(child.getId())) {
                    child.setCreateTime(now);
                }
                allEnums.add(child);
            }
            allEnums.add(allEnum);
            allEnumService.upsert(allEnums);
        }
        return allEnum;
    }

    @Override
    public int deleteAllEnum(Integer id) {
        return allEnumService.deleteById(id) ? 1 : 0;
    }

    @Override
    public List<AllEnum> getByTypeList(IdsDto ids) {
        List<AllEnum> byTypeList = allEnumService.getByTypeList(ids);
        if (byTypeList.isEmpty()) {
            return byTypeList;
        }
        byTypeList.sort(Comparator.comparing(AllEnum::getOrderNo));

        Map<Integer, List<AllEnum>> typeAndEnumsMap = new HashMap<>(byTypeList.size());

        for (int i = 0; i < byTypeList.size(); i++) {
            AllEnum allEnum = byTypeList.get(i);
            if (!ids.getIds().contains(allEnum.getId())) {
                byTypeList.remove(i--);
            }

            // 设置下一级
            if (typeAndEnumsMap.containsKey(allEnum.getId())) {
                allEnum.setChildren(typeAndEnumsMap.get(allEnum.getId()));
            } else {
                List<AllEnum> children = new LinkedList<>();
                typeAndEnumsMap.put(allEnum.getId(), children);
                allEnum.setChildren(children);
            }

            // 设置上一级
            if (typeAndEnumsMap.containsKey(allEnum.getEnumType())) {
                typeAndEnumsMap.get(allEnum.getEnumType()).add(allEnum);
            } else {
                List<AllEnum> parent = new LinkedList<>();
                parent.add(allEnum);
                typeAndEnumsMap.put(allEnum.getEnumType(), parent);
            }
        }

        return byTypeList;
    }
}
